﻿using AutoMapper;
using JuCheap.Core.Data.Entity;
using JuCheap.Core.Infrastructure.Extentions;
using JuCheap.Core.Infrastructure.Utilities;
using JuCheap.Core.IRepository;
using JuCheap.Core.IService.AppService;
using JuCheap.Core.Model;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace JuCheap.Core.Service.AppService
{
    /// <summary>
    /// 产品保存服务
    /// </summary>
    public class ProductSaveService : IProductSaveService
    {
        private readonly IProductRepository _productRepository;
        private readonly IProductSpecRepository _productSpecRepository;
        private readonly IProductImageRepository _productImageRepository;
        private readonly IUnitWork _unitWork;
        private readonly IMapper _mapper;

        /// <summary>
        /// ctor
        /// </summary>
        public ProductSaveService(IProductRepository productRepository,
            IProductSpecRepository productSpecRepository,
            IProductImageRepository productImageRepository,
            IUnitWork unitWork,
            IMapper mapper)
        {
            _productRepository = productRepository;
            _productSpecRepository = productSpecRepository;
            _productImageRepository = productImageRepository;
            _mapper = mapper;
            _unitWork = unitWork;
        }

        /// <summary>
        /// 创建产品
        /// </summary>
        /// <param name="req">产品保存模型</param>
        /// <returns></returns>
        public async Task<string> CreateAsync(ProductCreateRequestDto req)
        {
            using (await _unitWork.BeginTransactionAsync())
            {
                var productId = SnowFlake.NewId();

                //保存产品基础信息
                var product = _mapper.Map<ProductCreateRequestDto, Product>(req);
                product.Id = productId;
                await _productRepository.InsertAsync(product);

                //保存产品规格信息
                if (req.SpecNames.AnyOne())
                {
                    var specLength = req.SpecNames.Count();
                    var specList = new List<ProductSpec>();
                    for(var i = 0; i < specLength; i++)
                    {
                        specList.Add(new ProductSpec
                        {
                            ProductId = productId,
                            SpecName = req.SpecNames[i],
                            SpecValue = req.SpecValues[i]
                        });
                    }
                    await _productSpecRepository.BatchInsertAsync(specList);
                }

                //保存产品图片
                if (req.Images.AnyOne())
                {
                    var images = _mapper.Map<List<ProductImageDto>, List<ProductImage>>(req.Images.Where(x => x.ImageUrl.IsNotBlank()).ToList());
                    images.ForEach(x => x.ProductId = productId);
                    await _productImageRepository.BatchInsertAsync(images);
                }

                await _unitWork.CommitAsync();
                return productId;
            }
        }

        /// <summary>
        /// 保存产品
        /// </summary>
        /// <param name="req">产品保存模型</param>
        /// <returns></returns>
        public async Task<string> UpdateAsync(ProductEditRequestDto req)
        {
            using (await _unitWork.BeginTransactionAsync())
            {
                //保存产品基础信息
                var product = _mapper.Map<ProductEditRequestDto, Product>(req);
                await _productRepository.UpdateAsync(product);

                //保存产品规格信息
                await _productSpecRepository.DeleteAsync(x => x.ProductId == req.Id);
                if (req.SpecNames.AnyOne())
                {
                    var specLength = req.SpecNames.Count();
                    var specList = new List<ProductSpec>();
                    for (var i = 0; i < specLength; i++)
                    {
                        specList.Add(new ProductSpec
                        {
                            ProductId = req.Id,
                            SpecName = req.SpecNames[i],
                            SpecValue = req.SpecValues[i]
                        });
                    }
                    await _productSpecRepository.BatchInsertAsync(specList);
                }

                //保存产品图片
                await _productImageRepository.DeleteAsync(x => x.ProductId == req.Id);
                if (req.Images.AnyOne())
                {
                    var images = _mapper.Map<List<ProductImageDto>, List<ProductImage>>(req.Images.Where(x => x.ImageUrl.IsNotBlank()).ToList());
                    images.ForEach(x => x.ProductId = req.Id);
                    await _productImageRepository.BatchInsertAsync(images);
                }

                await _unitWork.CommitAsync();
                return req.Id;
            }
        }
    }
}
